module BMG_Write (
    // input wire rst_n,     // 复位信号低有效
    input wire clk_in,  // 时钟
    input wire flag,    // 写标志 上升沿有效
    input wire [7:0] sdata_in,
    input wire read_ack,    // BRAM读完成信号 高有效 使all_data_valid变低

    // Block Memory Generator接口
    output reg [3:0]  bram_we = 4'h0,    // BRAM写使能
    output reg [31:0] bram_addr = 32'h0,  // BRAM地址
    output reg [31:0] bram_din = 32'h0,   // BRAM数据输入
    output reg        bram_en = 1'b0,     // BRAM使能
    output wire       bram_rst_n,
    // output wire       bram_clk,  // 不用的时钟
    output reg        all_data_valid = 1'b0    // 所有320字节数据接收完成
);

// 3位移位寄存器
reg [2:0] shift_reg_flag = 3'd0;
wire flag_vaild;
reg [2:0] shift_reg_ack = 3'd0;
wire read_ack_valid;


// assign bram_clk = clk_in;
assign bram_rst_n = 1'b1;

// 状态定义
localparam IDLE   = 3'b000;
localparam PULSE1 = 3'b001;
localparam PULSE2 = 3'b010;
localparam PULSE3 = 3'b011;
localparam PULSE4 = 3'b100;
localparam LAST_BRAM_ADDR = 32'd1276;
// localparam LAST_BRAM_ADDR = 32'd4;

// 状态寄存器声明
reg [3:0] current_state = IDLE;
reg [3:0] next_state = IDLE;


// 处理flag和read_ack信号
always @(posedge clk_in) begin
    shift_reg_flag <= {shift_reg_flag[1:0], flag};
    shift_reg_ack  <= {shift_reg_ack[1:0], read_ack};
end

assign flag_vaild     = (shift_reg_flag == 3'b011);
assign read_ack_valid = (shift_reg_ack  == 3'b011);

// 三段式状态机  第一段：状态寄存器 
always @(posedge clk_in) begin
    current_state <= next_state;  // 每个时钟更新状态
end


// 第二段：次态逻辑 逻辑转换
always @(*) begin
// 默认保持当前状态
next_state = current_state;

case (current_state)
    IDLE: begin
    if (flag_vaild == 1'b1)  // 启动条件
        next_state = PULSE1;
    end

    PULSE1: begin
    next_state = PULSE2;  // 无条件转换
    end

    PULSE2: begin
    next_state = PULSE3;  // 无条件转换
    end

    PULSE3: begin
    next_state = PULSE4;  // 无条件转换
    end

    PULSE4: begin
    next_state = IDLE;  // 回到初始状态
    end

    default: begin
    next_state = IDLE;  // 异常情况回到IDLE
    end
endcase
end


// 第三段：输出逻辑 
always @(posedge clk_in) begin
    case (current_state)
    IDLE: begin
        bram_en   <= 1'b0;
        bram_we   <= 4'h0;
        if (read_ack_valid == 1'b1) begin
            all_data_valid <= 1'b0;
        end else begin
            all_data_valid <= all_data_valid;
        end
    end

    PULSE1: begin  // 第一个脉冲实现使能和地址数据准备
        bram_en  <= 1'b1;
        bram_din <= {bram_din[31:8], sdata_in[7:0]};
        all_data_valid <= 1'b0; // 接收完成指示信号清零
    end

    PULSE2: begin  // 第二个脉冲实现写使能
        bram_we <= 4'hF;
    end

    PULSE3: begin  // 第三个脉冲保持不动作 实现数据写入
        ;
    end

    PULSE4: begin  // 第四个脉冲完成写入
        bram_en <= 1'b0;
        bram_we <= 4'h0;

        if (bram_addr == LAST_BRAM_ADDR) begin       // 写完320次后地址清零 
            bram_addr <= 32'd0;
            all_data_valid <= 1'b1; // 数据写入完成 设置标志
        end else begin
            bram_addr <= bram_addr + 32'd4;
        end
    end
    endcase
end


endmodule
